<script setup lang="tsx">
import { type Ref, computed, nextTick, onMounted, onUnmounted, ref, shallowRef, watch } from 'vue';
import type { TreeOption } from 'naive-ui';
import { NInput, NPopconfirm, useMessage } from 'naive-ui';
import * as monaco from 'monaco-editor';
import SvgIcon from '@/components/_builtin/svg-icon/index.vue';
import { deleteFile, getFile, treeFile, updateFile } from '@/service/api/cms';
import TemplateFileDrawer from './template-file-drawer.vue';
import TemplateFileUploadDrawer from './template-file-upload-drawer.vue';

defineOptions({
  name: 'TemplateDesignDrawer'
});

interface Props {
  /** the edit row data */
  rowData?: Api.Model | null;
}

const props = defineProps<Props>();
const message = useMessage();
const editorContainer = ref(null);
const emptyNode: Api.Node = { id: '', parentId: '', type: 0, children: null };
const fileNode = ref<Api.Node>(emptyNode as Api.Node);
const fileModel = ref<Api.Model>();

let editor: monaco.editor.IStandaloneCodeEditor;
const visible = defineModel<boolean>('visible', {
  default: false
});

const fileVisible = ref(false);
const fileOperateType = ref<NaiveUI.TableOperateType>('add');
const fileUploadVisible = ref(false);
const disableSave = ref<boolean>(true);

const title = computed(() => {
  if (props.rowData) {
    return `设计 - ${props.rowData.name} [ ${props.rowData.code} ]`;
  }

  return '设计';
});

function closeDrawer() {
  visible.value = false;
}

watch(visible, () => {
  if (visible.value) {
    // Initialize editor when drawer opens
    nextTick(() => {
      renderMonacoEditor();
    });

    getColumnData();
  } else {
    destroyMonacoEditor();
  }
});

function renderMonacoEditor() {
  if (editorContainer.value) {
    // Dispose existing editor if any
    destroyMonacoEditor();

    editor = monaco.editor.create(editorContainer.value, {
      language: 'javascript',
      theme: 'hc-light',
      readOnly: false,
      readOnlyMessage: { value: '不可修改', supportThemeIcons: true, supportHtml: true },
      codeLens: true,
      folding: true,
      snippetSuggestions: 'inline',
      tabCompletion: 'on',
      foldingStrategy: 'auto',
      smoothScrolling: true,
      automaticLayout: true // Add automatic layout to handle resize
    });
  }
}

function destroyMonacoEditor() {
  if (editor) {
    editor.dispose();
  }
}

// function editCode() {
// if(editor.value) {
//   let codeEditor = editor.value as monaco.editor.IStandaloneCodeEditor;
//   codeEditor.setr
// }
// }

async function saveCode() {
  const result = await updateFile({
    id: fileNode.value.id.toString(),
    templateId: props.rowData?.id,
    content: editor.getValue()
  });

  if (result) {
    message.info('保存成功');
  } else {
    message.error('保存失败');
  }
}

/** tree pattern name , use tree search */
const name: Ref<string> = ref('');
const columnData = shallowRef<TreeOption[]>([]);

async function getColumnData() {
  if (props.rowData) {
    const data = await treeFile({ templateId: props.rowData.id as number });
    if (data) {
      columnData.value = data.map(recursive);
    }
  }
}

function recursive(item: Api.Node): TreeOption {
  const result: TreeOption = {
    ...item,
    children: item.children ? item.children.map(recursive) : undefined
  };

  return result;
}

/** tree select handle */
async function handleSelectKeys(node: TreeOption | null, action: string) {
  // 点击一次是选择select,再点击一次是unselect
  if (action === 'select' && node) {
    disableSave.value = true;
    fileNode.value = {
      id: node.id as string,
      parentId: node.parentId as string,
      name: node.name,
      children: null,
      type: node.type as number
    };

    if (!node.type || node.type === 1) {
      editor.setValue('目录不支持编辑');
      return;
    }

    const suffix = node.suffix ? String(node.suffix) : '';
    if (suffix === 'html' || suffix === 'js' || suffix === 'css') {
      const data = await getFile({ id: node.id as string, templateId: props.rowData?.id as number });
      if (data) {
        editor.setValue(data);
        disableSave.value = false;
      }
    } else {
      editor.setValue('不支持编辑的格式');
    }
  }
}

onMounted(() => {});

onUnmounted(() => {});

// 创建文件夹
async function handleCreateFolder() {
  if (fileNode.value) {
    fileVisible.value = true;
    fileOperateType.value = 'add';
    if (fileNode.value.type === 1) {
      fileModel.value = {
        id: '',
        parentId: fileNode.value?.id,
        type: 1,
        templateId: props.rowData?.id
      };
    } else {
      fileModel.value = {
        id: '',
        parentId: fileNode.value?.parentId,
        type: 1,
        templateId: props.rowData?.id
      };
    }
  }
}

// 创建文件
async function handleCreateFile() {
  if (fileNode.value) {
    fileVisible.value = true;
    fileOperateType.value = 'add';
    if (fileNode.value.type === 1) {
      fileModel.value = {
        id: '',
        parentId: fileNode.value?.id,
        name: '',
        type: 2,
        templateId: props.rowData?.id
      };
    } else {
      fileModel.value = {
        id: '',
        parentId: fileNode.value?.parentId,
        name: '',
        type: 2,
        templateId: props.rowData?.id
      };
    }
  }
}

// 重命名文件或文件夹
async function handleRename() {
  if (!fileNode.value.id) {
    message.error('请先选择要删除的文件或文件夹');
    return;
  }

  if (fileNode.value) {
    fileVisible.value = true;
    fileOperateType.value = 'edit';
    fileModel.value = {
      id: fileNode.value?.id,
      parentId: fileNode.value?.parentId,
      name: fileNode.value?.name,
      type: fileNode.value?.type,
      templateId: props.rowData?.id
    };
  }
}

async function handleUpload() {
  // uploadRef.value?.openOpenFileDialog();
  if (fileNode.value) {
    fileUploadVisible.value = true;
    fileOperateType.value = 'add';
    if (fileNode.value.type === 1) {
      fileModel.value = {
        id: '',
        parentId: fileNode.value?.id,
        name: '',
        type: 2,
        templateId: props.rowData?.id
      };
    } else {
      fileModel.value = {
        id: '',
        parentId: fileNode.value?.parentId,
        name: '',
        type: 2,
        templateId: props.rowData?.id
      };
    }
  }
}

// 删除文件或文件夹
async function handleDelete() {
  if (!fileNode.value.id) {
    message.error('请先选择要删除的文件或文件夹');
    return;
  }

  try {
    const result = await deleteFile({ id: fileNode.value.id });
    if (result) {
      message.success('删除成功');
      fileNode.value = emptyNode;
      editor.setValue('');
      await getColumnData();
    }
    message.error('删除失败');
  } catch (_error) {
    console.error(_error);
    message.error('删除时发生错误');
  }
}

async function refresh() {
  fileModel.value = { ...emptyNode };

  await getColumnData();
}
</script>

<template>
  <NDrawer v-model:show="visible" display-directive="show" width="100%" @on-after-leave="closeDrawer">
    <NDrawerContent :title="title" :native-scrollbar="false" closable>
      <NSplit :size="0.2" pane1-class="pr-2" pane2-class="pl-2" :resize-trigger-size="0">
        <template #1>
          <div class="min-h-600px flex-col-stretch gap-16px overflow-hidden lt-sm:overflow-auto">
            <NCard title="文件列表" :bordered="true" size="small" class="sm:flex-1-hidden card-wrapper">
              <NInput v-model:value="name" placeholder="请输入文件名称" clearable />
              <NSpace justify="space-between" class="m-t-2">
                <NButton quaternary size="small" type="primary" @click="handleCreateFolder">
                  <template #icon>
                    <SvgIcon icon="material-symbols:create-new-folder-outline" />
                  </template>
                </NButton>
                <NButton quaternary size="small" type="primary" @click="handleCreateFile">
                  <template #icon>
                    <SvgIcon icon="material-symbols:add-card-outline" />
                  </template>
                </NButton>
                <NButton quaternary size="small" type="primary" @click="handleRename">
                  <template #icon>
                    <SvgIcon icon="material-symbols:edit-outline" />
                  </template>
                </NButton>
                <NButton quaternary size="small" type="primary" @click="handleUpload">
                  <template #icon>
                    <SvgIcon icon="material-symbols:drive-folder-upload-outline" />
                  </template>
                </NButton>
                <NPopconfirm @on-positive-click="() => handleDelete()">
                  <template #trigger>
                    <NButton quaternary size="small" type="error" @click="handleDelete">
                      <template #icon>
                        <SvgIcon icon="material-symbols:delete-outline" />
                      </template>
                    </NButton>
                  </template>
                  确认删除吗？
                </NPopconfirm>
              </NSpace>

              <NScrollbar class="m-t-2 max-h-600px min-h-600px" x-scrollable>
                <NTree
                  :default-expand-all="true"
                  :data="columnData"
                  :show-line="true"
                  :pattern="name"
                  block-line
                  key-field="id"
                  label-field="name"
                  :show-irrelevant-nodes="false"
                  class="gap-16px"
                  @update-selected-keys="(_key, _option, { node, action }) => handleSelectKeys(node, action)"
                />
              </NScrollbar>
            </NCard>
          </div>
        </template>
        <template #2>
          <div class="m-l-2 max-h-750px min-h-600px overflow-hidden lt-sm:overflow-auto">
            <NCard :bordered="true" size="small" class="sm:flex-1-hidden card-wrapper">
              <template #header>
                {{ fileNode?.type === 1 ? '目录' : '文件' }}&nbsp;
                <NTag type="info" size="small">{{ fileNode?.id }}</NTag>
              </template>
              <template #header-extra>
                <NButton type="primary" ghost size="small" :disabled="disableSave" @click="saveCode()">
                  <template #icon>
                    <SvgIcon icon="material-symbols:save-outline" />
                  </template>
                  保存
                </NButton>
              </template>
              <div ref="editorContainer" class="monaco-editor m-1"></div>
            </NCard>
          </div>
        </template>
      </NSplit>
      <template #footer>
        <NSpace :size="16">
          <NButton @click="closeDrawer">关闭</NButton>
        </NSpace>
      </template>
    </NDrawerContent>

    <TemplateFileDrawer
      v-model:visible="fileVisible"
      :operate-type="fileOperateType"
      :row-data="fileModel"
      @submitted="refresh"
    />
    <TemplateFileUploadDrawer v-model:visible="fileUploadVisible" :row-data="fileModel" @submitted="refresh" />
  </NDrawer>
</template>

<style scoped>
.site-select {
  width: 220px;
}

.monaco-editor {
  height: 750px;
  /* width: 600px; */
}
</style>
